#pragma once

/**
 * @file pipeline.h
 * @brief 配置流水线框架的核心接口与数据结构声明。
 * @details 定义插件接口（Provider/Transformer/Validator/Sink）、插件注册表、
 *          流水线规范与运行器，以及通用的插件选项校验工具。
 */

#include "config.h"

#include <functional>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>

// 辅助宏：安全拼接唯一名称（基于 __LINE__）
#define CFG_PW_CAT(a, b) a##b
#define CFG_PW_CAT2(a, b) CFG_PW_CAT(a, b)

namespace cfg
{

/**
 * @brief 插件通用描述信息。
 */
struct PluginDescriptor
{
    std::string name;     ///< 插件名称（唯一标识）
    std::string category; ///< 插件类别：provider/transformer/validator
    std::string version;  ///< 可选的版本信息
};

/**
 * @brief 插件选项的键值映射类型。
 */
using PluginOptions = std::unordered_map<std::string, std::string>;

/**
 * @brief Provider 插件接口：提供配置来源并写入到 Builder。
 */
class IProvider
{
public:
    virtual ~IProvider() = default;
    /**
     * @brief 执行来源读取，将结果写入到传入的 builder。
     * @param builder 目标构建器（可变）。
     * @param options 插件选项。
     * @param out_errors 阶段产生的错误应当追加到此处。
     * @return true 表示成功；false 表示发生错误（Runner 仍会合并错误信息）。
     */
    virtual bool provide(Builder & builder,
                         const PluginOptions & options,
                         std::vector<ConfigError> & out_errors) = 0;
};

/**
 * @brief Transformer 插件接口：在可变 Builder 上做变换。
 */
class ITransformer
{
public:
    virtual ~ITransformer() = default;
    /**
     * @brief 对传入的 builder 进行就地变换（规范化、替换、包含解析等）。
     * @param builder 目标构建器（可变）。
     * @param options 插件选项。
     * @param out_errors 阶段产生的错误应当追加到此处。
     * @return true 表示成功；false 表示发生错误，错误需写入 out_errors。
     */
    virtual bool transform(Builder & builder,
                           const PluginOptions & options,
                           std::vector<ConfigError> & out_errors) = 0;
};

/**
 * @brief Validator 插件接口：在只读 View 上做校验。
 */
class IValidator
{
public:
    virtual ~IValidator() = default;
    /**
     * @brief 基于只读视图执行校验，将诊断追加到 out_errors。
     * @param view 冻结后的只读视图。
     * @param options 插件选项。
     * @param out_errors 校验过程中产生的错误应当追加到此处。
     * @note 不返回 bool，校验失败以追加错误为准。
     */
    virtual void validate(const View & view,
                          const PluginOptions & options,
                          std::vector<ConfigError> & out_errors) = 0;
};

/**
 * @brief Sink 插件接口：在流水线末尾将结果快照进行输出（文件/标准输出/远端等）。
 */
class ISink
{
public:
    virtual ~ISink() = default;
    /**
     * @brief 对只读根对象执行输出（序列化写入文件、stdout、远端等）。
     * @param root 冻结后的只读根对象。
     * @param options 插件选项。
     * @param out_errors 输出过程中产生的错误应当追加到此处。
     * @return true 表示成功；false 表示发生错误（Runner 会合并错误但不改变 root）。
     */
    virtual bool write(const std::shared_ptr<const Object> & root,
                       const PluginOptions & options,
                       std::vector<ConfigError> & out_errors) = 0;
};

/**
 * @brief 插件工厂函数类型别名。
 */
using ProviderFactory = std::function<std::unique_ptr<IProvider>()>;
using TransformerFactory = std::function<std::unique_ptr<ITransformer>()>;
using ValidatorFactory = std::function<std::unique_ptr<IValidator>()>;
using SinkFactory = std::function<std::unique_ptr<ISink>()>;

/**
 * @brief 插件注册表（单例）。
 * @details 提供注册、创建、查询与列出已注册插件的能力。
 */
class PluginRegistry
{
public:
    /**
     * @brief 获取全局注册表实例。
     */
    static PluginRegistry & instance();

    /**
     * @brief 注册 provider 工厂。
     * @param name 插件名称。
     * @param factory 创建函数。
     */
    void register_provider(const std::string & name, ProviderFactory factory);
    /**
     * @brief 注册 transformer 工厂。
     * @param name 插件名称。
     * @param factory 创建函数。
     */
    void register_transformer(const std::string & name, TransformerFactory factory);
    /**
     * @brief 注册 validator 工厂。
     * @param name 插件名称。
     * @param factory 创建函数。
     */
    void register_validator(const std::string & name, ValidatorFactory factory);
    /**
     * @brief 注册 sink 工厂。
     * @param name 插件名称。
     * @param factory 创建函数。
     */
    void register_sink(const std::string & name, SinkFactory factory);

    /**
     * @brief 创建 provider 实例。
     * @param name 插件名称。
     * @return 对应实例；若未找到返回 nullptr。
     */
    std::unique_ptr<IProvider> create_provider(const std::string & name) const;
    /**
     * @brief 创建 transformer 实例。
     * @param name 插件名称。
     * @return 对应实例；若未找到返回 nullptr。
     */
    std::unique_ptr<ITransformer> create_transformer(const std::string & name) const;
    /**
     * @brief 创建 validator 实例。
     * @param name 插件名称。
     * @return 对应实例；若未找到返回 nullptr。
     */
    std::unique_ptr<IValidator> create_validator(const std::string & name) const;
    /**
     * @brief 创建 sink 实例。
     * @param name 插件名称。
     * @return 对应实例；若未找到返回 nullptr。
     */
    std::unique_ptr<ISink> create_sink(const std::string & name) const;

    /**
     * @brief 列出已注册的 provider 名称（字典序）。
     */
    std::vector<std::string> list_providers() const;
    /**
     * @brief 列出已注册的 transformer 名称（字典序）。
     */
    std::vector<std::string> list_transformers() const;
    /**
     * @brief 列出已注册的 validator 名称（字典序）。
     */
    std::vector<std::string> list_validators() const;
    /**
     * @brief 列出已注册的 sink 名称（字典序）。
     */
    std::vector<std::string> list_sinks() const;

    /**
     * @brief 判断给定类别与名称的插件是否存在。
     * @param category 取值为 "provider"/"transformer"/"validator"/"sink"。
     * @param name 插件名称。
     * @return 存在则返回 true；否则返回 false。
     */
    bool exists(const std::string & category, const std::string & name) const;

private:
    std::unordered_map<std::string, ProviderFactory> _providers;       ///< 已注册的 providers
    std::unordered_map<std::string, TransformerFactory> _transformers; ///< 已注册的 transformers
    std::unordered_map<std::string, ValidatorFactory> _validators;     ///< 已注册的 validators
    std::unordered_map<std::string, SinkFactory> _sinks;               ///< 已注册的 sinks
};

/**
 * @brief Provider 阶段的插件规范项。
 */
struct ProviderSpec
{
    std::string name;      ///< 插件名
    PluginOptions options; ///< 插件选项
};

/**
 * @brief Transformer 阶段的插件规范项。
 */
struct TransformerSpec
{
    std::string name;      ///< 插件名
    PluginOptions options; ///< 插件选项
};

/**
 * @brief Validator 阶段的插件规范项。
 */
struct ValidatorSpec
{
    std::string name;      ///< 插件名
    PluginOptions options; ///< 插件选项
};

/**
 * @brief Sink 阶段的插件规范项。
 */
struct SinkSpec
{
    std::string name;      ///< 插件名
    PluginOptions options; ///< 插件选项
};

/**
 * @brief 流水线规范：定义各阶段插件序列。
 */
struct PipelineSpec
{
    std::vector<ProviderSpec> providers;       ///< Provider 插件序列
    std::vector<TransformerSpec> transformers; ///< Transformer 插件序列
    std::vector<ValidatorSpec> validators;     ///< Validator 插件序列
    std::vector<SinkSpec> sinks;               ///< Sink 插件序列
};

/**
 * @brief 流水线运行结果。
 */
struct PipelineResult
{
    std::shared_ptr<const Object> root; ///< 冻结后的只读根对象
    std::vector<ConfigError> errors;    ///< 全量诊断信息
};

/**
 * @brief Runner：执行 providers→transformers→freeze→validators。
 */
class PipelineRunner
{
public:
    /**
     * @brief 按顺序执行流水线，并返回最终只读对象与诊断。
     * @param spec 流水线规范（各阶段插件与其选项）。
     * @return 结果对象与诊断信息。
     * @note 任何阶段的错误将累积到 result.errors；若 freeze 失败，validators 跳过。
     */
    [[nodiscard]] PipelineResult run(const PipelineSpec & spec) const;
};

// ---------------- 分散式附加注册表 ----------------
/**
 * @brief 分散式附加注册表：全局附加 transformers/validators。
 * @details 支持在各模块进行静态/动态注册，运行时统一收集并按优先级稳定排序。
 */
class AttachmentRegistry
{
public:
    /**
     * @brief 获取全局附加注册表实例。
     */
    static AttachmentRegistry & instance();

    /**
     * @brief 附加一个 transformer 规格项（全局）。
     * @param spec 规格（名称与选项）。
     * @param priority 越小越先执行；相同优先级按注册顺序稳定。
     */
    void attach_transformer(TransformerSpec spec, int priority = 0);

    /**
     * @brief 附加一个 validator 规格项（全局）。
     * @param spec 规格（名称与选项）。
     * @param priority 越小越先执行；相同优先级按注册顺序稳定。
     */
    void attach_validator(ValidatorSpec spec, int priority = 0);

    /**
     * @brief 收集全部附加的 transformers（按优先级与注册顺序稳定排序）。
     */
    std::vector<TransformerSpec> collect_transformers() const;
    /**
     * @brief 收集全部附加的 validators（按优先级与注册顺序稳定排序）。
     */
    std::vector<ValidatorSpec> collect_validators() const;

private:
    struct TransformerAttach
    {
        TransformerSpec spec;
        int priority;
        std::size_t seq;
    };
    struct ValidatorAttach
    {
        ValidatorSpec spec;
        int priority;
        std::size_t seq;
    };

    mutable std::mutex _mtx;
    std::vector<TransformerAttach> _t;
    std::vector<ValidatorAttach> _v;
    std::size_t _seq_counter = 0; // 单调递增的注册序号，用于稳定排序
};

/**
 * @def REGISTER_PROVIDER
 * @brief 静态注册 provider 插件的辅助宏。
 * @param name 插件名称。
 * @param Type 插件类型（实现 ISourceProvider）。
 */
#define REGISTER_PROVIDER(name, Type)                                                              \
    namespace                                                                                      \
    {                                                                                              \
    struct AutoRegProvider_##Type                                                                  \
    {                                                                                              \
        AutoRegProvider_##Type()                                                                   \
        {                                                                                          \
            ::cfg::PluginRegistry::instance().register_provider(                                   \
                name, [] { return std::make_unique<Type>(); });                                    \
        }                                                                                          \
    };                                                                                             \
    static AutoRegProvider_##Type g_auto_reg_provider_##Type;                                      \
    }

/**
 * @def REGISTER_TRANSFORMER
 * @brief 静态注册 transformer 插件的辅助宏。
 * @param name 插件名称。
 * @param Type 插件类型（实现 ITransformer）。
 */
#define REGISTER_TRANSFORMER(name, Type)                                                           \
    namespace                                                                                      \
    {                                                                                              \
    struct AutoRegTransformer_##Type                                                               \
    {                                                                                              \
        AutoRegTransformer_##Type()                                                                \
        {                                                                                          \
            ::cfg::PluginRegistry::instance().register_transformer(                                \
                name, [] { return std::make_unique<Type>(); });                                    \
        }                                                                                          \
    };                                                                                             \
    static AutoRegTransformer_##Type g_auto_reg_transformer_##Type;                                \
    }

/**
 * @def REGISTER_VALIDATOR
 * @brief 静态注册 validator 插件的辅助宏。
 * @param name 插件名称。
 * @param Type 插件类型（实现 IValidator）。
 */
#define REGISTER_VALIDATOR(name, Type)                                                             \
    namespace                                                                                      \
    {                                                                                              \
    struct AutoRegValidator_##Type                                                                 \
    {                                                                                              \
        AutoRegValidator_##Type()                                                                  \
        {                                                                                          \
            ::cfg::PluginRegistry::instance().register_validator(                                  \
                name, [] { return std::make_unique<Type>(); });                                    \
        }                                                                                          \
    };                                                                                             \
    static AutoRegValidator_##Type g_auto_reg_validator_##Type;                                    \
    }

/**
 * @def REGISTER_SINK
 * @brief 静态注册 sink 插件的辅助宏。
 * @param name 插件名称。
 * @param Type 插件类型（实现 ISink）。
 */
#define REGISTER_SINK(name, Type)                                                                  \
    namespace                                                                                      \
    {                                                                                              \
    struct AutoRegSink_##Type                                                                      \
    {                                                                                              \
        AutoRegSink_##Type()                                                                       \
        {                                                                                          \
            ::cfg::PluginRegistry::instance().register_sink(                                       \
                name, [] { return std::make_unique<Type>(); });                                    \
        }                                                                                          \
    };                                                                                             \
    static AutoRegSink_##Type g_auto_reg_sink_##Type;                                              \
    }

/**
 * @def CFG_ADD_TRANSFORMER
 * @brief 静态地附加一个 transformer 规格（全局）。
 * @param name 插件名称字面量。
 * @param options PluginOptions 初始化表达式（如 {{"path","x"},{"min","1"}}）。
 * @param priority 越小越先执行。
 */
#define CFG_ADD_TRANSFORMER(name, options, priority)                                               \
    namespace                                                                                      \
    {                                                                                              \
    struct AutoAttachTransformer_Line_##__LINE__                                                   \
    {                                                                                              \
        AutoAttachTransformer_Line_##__LINE__()                                                    \
        {                                                                                          \
            ::cfg::TransformerSpec _spec;                                                          \
            _spec.name = (name);                                                                   \
            _spec.options = (options);                                                             \
            ::cfg::AttachmentRegistry::instance().attach_transformer(std::move(_spec),             \
                                                                     (priority));                  \
        }                                                                                          \
    };                                                                                             \
    static AutoAttachTransformer_Line_##__LINE__ g_auto_attach_transformer_Line_##__LINE__;        \
    }

/**
 * @def CFG_ADD_VALIDATOR
 * @brief 静态地附加一个 validator 规格（全局）。
 * @param name 插件名称字面量。
 * @param options PluginOptions 初始化表达式（如 {{"path","x"},{"min","1"}}）。
 * @param priority 越小越先执行。
 */
#define CFG_ADD_VALIDATOR(name, options, priority)                                                 \
    namespace                                                                                      \
    {                                                                                              \
    struct AutoAttachValidator_Line_##__LINE__                                                     \
    {                                                                                              \
        AutoAttachValidator_Line_##__LINE__()                                                      \
        {                                                                                          \
            ::cfg::ValidatorSpec _spec;                                                            \
            _spec.name = (name);                                                                   \
            _spec.options = (options);                                                             \
            ::cfg::AttachmentRegistry::instance().attach_validator(std::move(_spec), (priority));  \
        }                                                                                          \
    };                                                                                             \
    static AutoAttachValidator_Line_##__LINE__ g_auto_attach_validator_Line_##__LINE__;            \
    }

/**
 * @brief 插件选项校验与帮助输出（通用工具）。
 */
namespace plugin
{

/**
 * @brief 选项规范：用于声明插件支持的各个选项及其约束。
 */
struct PluginOptionSpec
{
    std::string name;                         ///< 选项名（键）
    bool required = false;                    ///< 是否必填
    std::vector<std::string> enum_values;     ///< 若非空，则限定取值集合
    std::string description;                  ///< 选项描述（用于帮助输出）
    std::optional<std::string> default_value; ///< 默认值（可选）
};

/**
 * @brief 选项检查器：为插件提供统一的选项校验、解析与帮助文本。
 */
class PluginOptionsChecker
{
public:
    /**
     * @brief 构造校验器，绑定插件名与选项表。
     * @param plugin_name 用于错误消息前缀。
     * @param options 调用方传入的选项映射。
     */
    explicit PluginOptionsChecker(std::string plugin_name, const PluginOptions & options);

    /**
     * @brief 添加一条选项规范（可多次调用添加多项）。
     * @param spec 选项规范。
     */
    void add_spec(PluginOptionSpec spec);

    /**
     * @brief 按照已添加的规范批量校验（必填项、枚举集合）。
     * @param out_errors 失败时将错误追加到此处。
     * @return 全部通过返回 true；否则返回 false。
     */
    bool validate(std::vector<ConfigError> & out_errors) const;

    /**
     * @brief 生成帮助文本（多行）。
     * @details 包含每个选项的名称、是否必填、默认值、枚举集合与描述。
     */
    std::string build_help_text() const;

    /**
     * @name 解析辅助
     * @brief 从字符串安全解析为具体类型。
     * @{
     */

    /**
     * @brief 取得字符串选项；若不存在且提供了默认值，则返回默认值。
     * @param key 选项键。
     * @param default_value 可选默认值。
     */
    expected<std::string, ConfigError>
    get_string(const std::string & key,
               std::optional<std::string> default_value = std::nullopt) const;

    /**
     * @brief 解析为 int64；若不存在且提供默认值则返回默认；若转换失败返回错误。
     * @param key 选项键。
     * @param default_value 可选默认值。
     */
    expected<int64_t, ConfigError>
    get_int64(const std::string & key, std::optional<int64_t> default_value = std::nullopt) const;

    /**
     * @brief 解析为 double；若不存在且提供默认值则返回默认；若转换失败返回错误。
     * @param key 选项键。
     * @param default_value 可选默认值。
     */
    expected<double, ConfigError>
    get_double(const std::string & key, std::optional<double> default_value = std::nullopt) const;

    /**
     * @brief 解析为 bool；接受 true/false/1/0（大小写不敏感）。
     * @param key 选项键。
     * @param default_value 可选默认值。
     */
    expected<bool, ConfigError> get_bool(const std::string & key,
                                         std::optional<bool> default_value = std::nullopt) const;

    /** @} */

private:
    std::string _plugin_name;             ///< 插件名（用于错误消息前缀）
    const PluginOptions & _options;       ///< 选项映射的引用（外部维护生命周期）
    std::vector<PluginOptionSpec> _specs; ///< 已添加的选项规范列表
};

} // namespace plugin

} // namespace cfg